#include <stdio.h>
#include <unistd.h>
#include "thread_ctrl.h"

/* 进程调用使能 SIGINT 和 SIGTERM 的阻塞 */
void init_process_signal_handle(pthread_t *tid, void *(handler)(void *arg), struct thread_info_t *thread)
{
    /* 1. 主进程阻塞 SIGINT 和 SIGTERM */
    sigset_t block_set;
    sigemptyset(&block_set);
    sigaddset(&block_set, SIGINT);
    sigaddset(&block_set, SIGTERM);
    /* 所有继承此掩码的线程都会阻塞这些信号 */
    pthread_sigmask(SIG_BLOCK, &block_set, NULL);
    /* 2. 创建专门的信处理号线程 */
    pthread_create(tid, NULL, handler, thread);
}

/* 线程取消 SIGUSR1 的阻塞 */
void init_thread_user_signal(void)
{
    /* 检查当前线程阻塞了哪些信号 */
    sigset_t current_mask;
    pthread_sigmask(SIG_SETMASK, NULL, &current_mask);
    if (sigismember(&current_mask, SIGINT)) {
        // printf("WARN: SIGINT is blocked in thread %s\n");
    } else {
        // printf("INFO: SIGINT is not blocked in thread %s\n");
    }
    /* 在新线程中取消对 SIGUSR1 的阻塞 */
    sigset_t set;
    sigemptyset(&set);
    sigaddset(&set, SIGUSR1);
    pthread_sigmask(SIG_UNBLOCK, &set, NULL);
    // printf("INFO: SIGUSR1 is not blocked in thread %s\n");
}

/* 专门的信号处理线程 */
void *signal_handler_thread(void* arg)
{
    struct thread_info_t *thread = (struct thread_info_t *)arg;
    sigset_t set;
    int sig;
    int i = 0;

    /* 设置需要监听的信号集：
     * 程序终止请求(SIGINT)和系统终止信号(SIGTERM)
     */
    sigemptyset(&set);
    sigaddset(&set, SIGINT);
    sigaddset(&set, SIGTERM);
    while (1) {
        /* 同步等待信号到来 */
        if (sigwait(&set, &sig) == 0) {
            if (sig == SIGINT) {
                printf("INFO: Caught SIGINT signal, instructing all threads to terminate...\n");
                for (i = 0; i < thread->num; i++) {
                    thread->param[i].exit_sig = 1;
                    sleep(1);
                    if (thread->param[i].id != 0) {
                        pthread_kill(thread->param[i].id, SIGUSR1);
                        thread->param[i].id = 0;
                    }
                }
                break;
            }
        }
    }
    pthread_exit(NULL);
}
